﻿using System;
using System.Collections.Generic;

namespace TestApp.Historys
{
    public sealed class History
    {

        public bool CanUndo
        {
            get
            {
                if (this.Index < 0) return false;
                if (this.Index >= this.Items.Count) return false;
                return true;
            }
        }

        public bool CanRedo
        {
            get
            {
                if (this.Index + 1 < 0) return false;
                if (this.Index + 1 >= this.Items.Count) return false;
                return true;
            }
        }

        int Index = -1;
        readonly int Limit;
        readonly IList<HistoryBase> Items = new List<HistoryBase>();

        public History(int limit = 20)
        {
            this.Limit = limit;
        }

        public void Push(HistoryBase history)
        {
            if (this.Items.Count > 0)
            {
                for (int i = this.Items.Count - 1; i > this.Index; i--)
                {
                    this.Items.RemoveAt(i);
                }
            }

            if (this.Items.Count >= this.Limit)
            {
                this.Items.RemoveAt(0);
                this.Items.Add(history);
            }
            else
            {
                this.Index++;
                this.Items.Add(history);
            }
        }

        public bool Undo(Func<HistoryBase, bool> action)
        {
            if (this.CanUndo == false) return false;

            if (this.Items[this.Index] is HistoryBase history)
            {
                this.Index--;
                return action(history);
            }

            return false;
        }

        public bool Redo(Func<HistoryBase, bool> action)
        {
            if (this.CanRedo == false) return false;

            if (this.Items[this.Index + 1] is HistoryBase history)
            {
                this.Index++;
                return action(history);
            }

            return false;
        }

        public void Clear()
        {
            this.Index = -1;
            this.Items.Clear();
        }

    }
}